/*
 * Copyright 2017 JessYan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.jessyan.art.integration;


import me.jessyan.art.base.delegate.AbilityDelegateImpl;

import ohos.aafwk.ability.Ability;

import ohos.utils.PacMap;
import org.jetbrains.annotations.NotNull;



import me.jessyan.art.base.delegate.AbilityDelegate;
import me.jessyan.art.base.delegate.IAbility;
import me.jessyan.art.integration.cache.Cache;
import me.jessyan.art.integration.cache.IntelligentCache;
import me.jessyan.art.utils.Preconditions;
import ohos.aafwk.ability.AbilityLifecycleCallbacks;

import javax.inject.Inject;
import javax.inject.Singleton;


/**
 * ================================================
 * {@link ohos.aafwk.ability.AbilityLifecycleCallbacks} 默认实现类
 * 通过 {@link AbilityDelegate} 管理 {link Activity}
 *
 * @see <a href="http://www.jianshu.com/p/75a5c24174b2">ActivityLifecycleCallbacks 分析文章</a>
 * Created by JessYan on 21/02/2017 14:23
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * ================================================
 */
@Singleton
public class AbilityLifecycle implements AbilityLifecycleCallbacks {
    @Inject
    AppManager mAppManager;
    @Inject
     Ability mApplication;
    @Inject
      Cache<String, Object> mExtras;
//    @Inject
//    Lazy<AbilityLifecycleCallbacks> mFractionLifecycle;
//    @Inject
//    Lazy<List<AbilityLifecycleCallbacks>> mFractionLifecycles;

    @Inject
    public AbilityLifecycle() {

    }

    @Override
    public void onAbilityStart(Ability ability) {
        //如果 intent 包含了此字段,并且为 true 说明不加入到 list 进行统一管理
        boolean isNotAdd = false;
        if (ability.getIntent() != null)
            isNotAdd = ability.getIntent().getBooleanParam(AppManager.IS_NOT_ADD_ACTIVITY_LIST, false);

        if (!isNotAdd)
            mAppManager.addActivity(ability);

        //配置abilityDelegate
        if (ability instanceof IAbility) {
            AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
            if (abilityDelegate == null) {
                Cache<String, Object> cache = getCacheFromActivity((IAbility) ability);
                abilityDelegate = new AbilityDelegateImpl(ability);
                //使用 IntelligentCache.KEY_KEEP 作为 key 的前缀, 可以使储存的数据永久存储在内存中
                //否则存储在 LRU 算法的存储空间中, 前提是 Activity 使用的是 IntelligentCache (框架默认使用)
                cache.put(IntelligentCache.getKeyOfKeep(AbilityDelegate.ACTIVITY_DELEGATE), abilityDelegate);
            }
            abilityDelegate.onStart(ability.getIntent());
        }
//        registerFragmentCallbacks(activity);
    }

    @Override
    public void onAbilityActive(Ability ability) {
        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onStart(ability.getIntent());
        }
    }

    @Override
    public void onAbilityInactive(Ability ability) {
        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onInactive();
        }
    }

    @Override
    public void onAbilityForeground(Ability ability) {
        mAppManager.setCurrentActivity(ability);

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onForeground(ability.getIntent());
        }
    }

    @Override
    public void onAbilityBackground(Ability ability) {
        mAppManager.setCurrentActivity(ability);

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onBackground();
        }
    }

    @Override
    public void onAbilityStop(Ability ability) {
        mAppManager.removeActivity(ability);

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onStop();
            getCacheFromActivity((IAbility) ability).clear();
        }
    }

    @Override
    public void onAbilitySaveState(PacMap pacMap) {

    }

    public void onActivityResumed(Ability ability) {
        mAppManager.setCurrentActivity(ability);

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onResume();
        }
    }

    public void onActivityPaused(Ability ability) {
        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onPause();
        }
    }

    public void onActivityStopped(Ability ability) {
        if (mAppManager.getCurrentActivity() == ability) {
            mAppManager.setCurrentActivity(null);
        }

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onStop();
        }
    }

    public void onActivitySaveInstanceState(Ability ability, PacMap outState) {
        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onSaveInstanceState(outState);
        }
    }

    public void onActivityDestroyed(Ability ability) {
        mAppManager.removeActivity(ability);

        AbilityDelegate abilityDelegate = fetchAbilityDelegate(ability);
        if (abilityDelegate != null) {
            abilityDelegate.onStop();
            getCacheFromActivity((IAbility) ability).clear();
        }
    }

    private AbilityDelegate fetchAbilityDelegate(Ability activity) {
        AbilityDelegate AbilityDelegate = null;
        if (activity instanceof IAbility) {
            Cache<String, Object> cache = getCacheFromActivity((IAbility) activity);
            AbilityDelegate = (AbilityDelegate) cache.get(IntelligentCache.getKeyOfKeep(AbilityDelegate.ACTIVITY_DELEGATE));
        }
        return AbilityDelegate;
    }

    @NotNull
    private Cache<String, Object> getCacheFromActivity(IAbility activity) {
        Cache<String, Object> cache = activity.provideCache();
        Preconditions.checkNotNull(cache, "%s cannot be null on Activity", Cache.class.getName());
        return cache;
    }
}
